﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace WorkflowDesigner.UI
{

    /// <summary>
    /// 流程控件基类
    /// </summary>
    public abstract class ShapeBase : IDisposable
    {
        /// <summary>
        /// 文字显示格式
        /// </summary>
        protected readonly StringFormat Format;

        private RectangleF _txtRange;

        /// <summary>
        /// 文字显示区域
        /// </summary>
        public RectangleF TxtRange
        {
            get
            {
                _txtRange.X = X;
                _txtRange.Y = Y;

                _txtRange.Width = Math.Abs(Width) > 30F ? Math.Abs(Width) : 30F;
                _txtRange.Height = Math.Abs(Height) > 12F ? Math.Abs(Height) : 12F;
                if (Width < 0) _txtRange.X -= _txtRange.Width;
                if (Height < 0) _txtRange.Y -= _txtRange.Height;
                return _txtRange;
            }
        }

        /// <summary>
        /// 是否鼠标指向对象
        /// </summary>
        public bool IsHovered { get; set; }

        /// <summary>
        /// 获取/设置选中
        /// </summary>
        public bool IsSelected { get; set; }

        /// <summary>
        /// 是否正在创建
        /// </summary>
        public bool IsCreating { get; set; }

        /// <summary>
        /// 控件Id
        /// </summary>
        public Guid Id { get; set; }

        /// <summary>
        /// 控件名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 控件位置 X
        /// </summary>
        public int X { get; set; }

        /// <summary>
        /// 控件位置 Y
        /// </summary>
        public int Y { get; set; }

        /// <summary>
        /// 控件宽
        /// </summary>
        public int Width { get; set; }

        /// <summary>
        /// 控件长
        /// </summary>
        public int Height { get; set; }

        private Color _color = Color.Black;

        /// <summary>
        /// 控件颜色
        /// </summary>
        public Color Color
        {
            get => IsCreating | IsSelected ? Color.FromArgb(_color.A / 3, _color) : _color;
            set => _color = value;
        }

        /// <summary>
        /// 控件字体
        /// </summary>
        public Font Font { get; set; }

        private Color _highLightColor = Color.FromArgb(251, 228, 94);

        /// <summary>
        /// 选中时高亮颜色
        /// </summary>
        protected Color HighLightColor => IsCreating | IsSelected
            ? Color.FromArgb(_highLightColor.A / 3, _highLightColor)
            : _highLightColor;

        private Brush _shapeBrush;

        /// <summary>
        /// 控件笔刷
        /// </summary>
        protected Brush ShapeBrush
        {
            get
            {
                ((SolidBrush) _shapeBrush).Color = Color;
                return _shapeBrush;
            }
            set => _shapeBrush = value;
        }

        /// <summary>
        /// 文字笔刷
        /// </summary>
        protected Brush TextBrush { get; set; }

        private Pen _pen = new Pen(Color.Black, 1F);

        /// <summary>
        /// 控件画笔
        /// </summary>
        protected Pen Pen
        {
            get
            {
                _pen.Color = IsSelected ? HighLightColor : Color.Black;
                _pen.Width = IsSelected ? 2F : 1F;
                return _pen;
            }
            set => _pen = value;
        }

        protected ShapeBase()
        {
            Format = new StringFormat
            {
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center,
            };
            Font = new Font("黑体", 10f);
            _shapeBrush = new SolidBrush(Color.White);
            TextBrush = new SolidBrush(Color.Black);

            IsCreating = true;
        }

        public virtual void Paint(Graphics graphics)
        {
            graphics.DrawString(Name, Font, TextBrush, TxtRange, Format);
        }

        public abstract bool Contian(Point p);

        public abstract Point? GetNearHandle(Point point);

        public void Dispose()
        {
            Format?.Dispose();
            _shapeBrush?.Dispose();
            _pen.Dispose();
            Font?.Dispose();
            TextBrush?.Dispose();
        }
    }
}
